package enet.imitate.common.builder;

import enet.imitate.common.Context;
import enet.imitate.common.Log;

/**
 * @Description TODO  </br>
 * @Author tonywang</br>
 * @DATE 4/9/2019 4:24 PM</br>
 */
public abstract class AbstractBuilder<T> implements Builder<T>{
    protected  final Log mLog = Log.of(getClass());
    /**
     * 功能开关
     */
    private boolean enabled = true;

    /**
     * Generate any Object and return it. If isEnabled() == false. Return null.
     * If isValid() == false return null.
     *
     * @param ctx . It contains the information needed to build the value.
     */
    @Override
    public T build(Context ctx) {
        if (!isEnabled() || !isValid(ctx)) return  null;
        return doBuild(ctx);
    }

    /**
     * Validate the current context. Return false if fails
     *
     * @param ctx GeneratorContext
     * @return
     */
    protected boolean isValid(Context pCtx) {
        return true;
    }

    /**
     * do build javaBean by context.
     *
     * @param ctx context
     * @return javaBean
     */
    protected abstract T doBuild(Context pCtx);


    /**
     * check whether params exists in pGeneratorContext.
     *
     * @param ctx generatorContext
     * @param keys
     * @return valid
     */
    protected boolean validateObjectInsideContext(Context ctx, Object... keys) {
        if (ctx == null || keys == null) {
            return true;
        }
        boolean valid = true;
        for (Object key : keys) {
            if (ctx.getAttr(key) == null) {
                valid = false;
                mLog.warn("当前 GeneratorContext 中, 不存在 key: " + key);
                break;
            }
        }
        return valid;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
    }

    public boolean isEnabled() {
        return enabled;
    }

    public AbstractBuilder setEnabled(boolean pEnabled) {
        enabled = pEnabled;
        return this;
    }
}
